package com.chen.recruit.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.chen.recruit.common.api.CommonResult;
import com.chen.recruit.common.constants.MessageConstants;
import com.chen.recruit.domain.RecruitPost;
import com.chen.recruit.domain.dto.PostClassifyDto;
import com.chen.recruit.domain.model.PageQuery;
import com.chen.recruit.mapper.RecruitPostMapper;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import com.chen.recruit.domain.PostClassify;
import com.chen.recruit.mapper.PostClassifyMapper;
import com.chen.recruit.service.PostClassifyService;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

/**
 * 岗位分类Service业务层处理
 *
 * @author cgy
 * @date 2022-08-20
 */
@Service
@RequiredArgsConstructor
public class PostClassifyServiceImpl extends ServiceImpl<PostClassifyMapper, PostClassify> implements PostClassifyService {

    private final RecruitPostMapper recruitPostMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public CommonResult addPostClassify(PostClassify postClassify) {
        if (checkClassifyNameUnique(postClassify)) {
            return CommonResult.fail(MessageConstants.CLASSIFY_NAME_REPEAT);
        }

        PostClassify parentPostClassify = baseMapper.selectById(postClassify.getParentId());

        if (ObjectUtil.isNotNull(parentPostClassify) && parentPostClassify.getLevelDepth() == 3) {
            return CommonResult.fail(MessageConstants.PARENT_CLASSIFY_FAIL);
        }

        return this.save(postClassify) ? CommonResult.success() : CommonResult.fail();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public CommonResult deletePostClassifyById(Integer id) {
        List<PostClassify> postClassifies = baseMapper.selectList(Wrappers
                .<PostClassify>lambdaQuery().eq(PostClassify::getParentId, id));
        if (CollUtil.isNotEmpty(postClassifies)) {
            return CommonResult.fail(MessageConstants.DELETE_CLASSIFY_ERROR);
        }

        boolean exists = recruitPostMapper.exists(Wrappers.<RecruitPost>lambdaQuery()
                .eq(RecruitPost::getPostClassifyId, id));
        if (exists) {
            return CommonResult.fail(MessageConstants.DELETE_CLASSIFY_FAIL);
        }

        return this.removeById(id) ? CommonResult.success() : CommonResult.fail();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public CommonResult updatePostClassify(PostClassify postClassify) {
        if (checkClassifyNameUnique(postClassify)) {
            return CommonResult.fail(MessageConstants.CLASSIFY_NAME_REPEAT);
        }

        PostClassify parentPostClassify = baseMapper.selectById(postClassify.getParentId());
        List<PostClassify> postClassifies = baseMapper.selectList(Wrappers.<PostClassify>lambdaQuery()
                .eq(PostClassify::getParentId, postClassify.getId()));

//        if (ObjectUtil.isNull(parentPostClassify)) {
//            postClassify.setLevelDepth(1);
//            if (CollUtil.isNotEmpty(postClassifies)) {
//                postClassifies = postClassifies.stream()
//                        .peek(item -> item.setLevelDepth(item.getLevelDepth() - 1))
//                        .collect(Collectors.toList());
//            }
//        } else {
//            if (parentPostClassify.getId().equals(postClassify.getId())) {
//                return CommonResult.fail(MessageConstants.PARENT_CLASSIFY_ERROR);
//            }
//
//            Integer parentLevelDepth = parentPostClassify.getLevelDepth();
//            Integer levelDepth = postClassify.getLevelDepth();
//
//            if (parentLevelDepth == 1 && (levelDepth == 2 || levelDepth == 3)) {
//                postClassify.setLevelDepth(2);
//                if (CollUtil.isNotEmpty(postClassifies)) {
//                    postClassifies = postClassifies.stream()
//                            .peek(item -> item.setLevelDepth(item.getLevelDepth() - 1))
//                            .collect(Collectors.toList());
//                }
//            } else if (parentLevelDepth == 2 && levelDepth == 3) {
//                postClassify.setLevelDepth(3);
//            } else {
//                return CommonResult.fail(MessageConstants.PARENT_CLASSIFY_FAIL);
//            }
//
//        }


        postClassifies.add(postClassify);

        return updateBatchById(postClassifies) ? CommonResult.success() : CommonResult.fail();
    }

    @Override
    public List<PostClassifyDto> getPostClassifyList(PostClassify params, PageQuery pageQuery) {
        List<PostClassifyDto> data;

        if (StringUtils.isBlank(params.getName()) && ObjectUtil.isNull(params.getLevelDepth())) {
            List<PostClassifyDto> postClassifies = BeanUtil.copyToList(this.list(), PostClassifyDto.class);
            data = postClassifies.stream().filter(item -> item.getParentId() == 0)
                    .peek(item -> item.setChildren(getChildrenPostClassifies(item.getId(), postClassifies)))
                    .collect(Collectors.toList());
        } else {
            List<PostClassify> postClassifies = baseMapper.selectList(Wrappers.<PostClassify>lambdaQuery()
                    .like(StringUtils.isNotBlank(params.getName()), PostClassify::getName, params.getName())
                    .eq(ObjectUtil.isNotNull(params.getLevelDepth()), PostClassify::getLevelDepth, params.getLevelDepth()));

            List<PostClassifyDto> postClassifyDtos = BeanUtil.copyToList(postClassifies, PostClassifyDto.class);

            for (int i = 0; i < postClassifies.size(); i++) {
                Integer id = postClassifies.get(i).getId();
                postClassifies.removeIf(item -> item.getParentId().equals(id));
            }

            List<PostClassifyDto> postClassifyDtoList = BeanUtil.copyToList(postClassifies, PostClassifyDto.class);

            data = postClassifyDtoList.stream().anyMatch(item -> item.getParentId() == 0) ?
                    postClassifyDtoList.stream().filter(item -> item.getParentId() == 0)
                            .peek(item -> item.setChildren(getChildrenPostClassifies(item.getId(), postClassifyDtos)))
                            .collect(Collectors.toList()) :
                    postClassifyDtoList.stream()
                            .peek(item -> item.setChildren(getChildrenPostClassifies(item.getId(), postClassifyDtos)))
                            .collect(Collectors.toList());
        }

        return data;
    }

    private boolean checkClassifyNameUnique(PostClassify params) {
        return baseMapper.exists(Wrappers.<PostClassify>lambdaQuery()
                .eq(PostClassify::getName, params.getName())
                .ne(ObjectUtil.isNotNull(params.getId()), PostClassify::getId, params.getId()));
    }

    private List<PostClassifyDto> getChildrenPostClassifies(Integer id, List<PostClassifyDto> postClassifyDtos) {
        return postClassifyDtos.stream().filter(item -> item.getParentId().equals(id))
                .peek(item -> item.setChildren(getChildrenPostClassifies(item.getId(), postClassifyDtos)))
                .collect(Collectors.toList());
    }

}
